package com.jjb.www.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.hjq.http.listener.HttpCallback;
import com.hjq.http.listener.OnHttpListener;
import com.hjq.toast.ToastUtils;
import com.hjq.widget.layout.WrapRecyclerView;
import com.jjb.www.R;
import com.jjb.www.app.AppAdapter;
import com.jjb.www.http.model.HttpListData;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;

import java.util.List;

import okhttp3.Call;

/**
 * Author: lkw
 * time:   2023/06/20 11:10
 * des:    垂直的下拉刷新上拉加载控件
 */

public class CommonRefreshView extends FrameLayout implements View.OnClickListener,
        OnRefreshLoadMoreListener, OnHttpListener<Object> {

    private final Context mContext;
    private DataHelper mDataHelper;
    private final int mLayoutRes;
    private View mContentView;
    private SmartRefreshLayout mSmartRefreshLayout;
    private WrapRecyclerView mRecyclerView;
    /**
     * 没有数据的View
     */
    private LinearLayout mEmptyLayout;
    /**
     * 加载失败View
     */
    private View mLoadFailureView;
    /**
     * 下拉刷新是否可用
     */
    private final boolean mRefreshEnable;
    /**
     * 上拉加载是否可用
     */
    private final boolean mLoadMoreEnable;
    /**
     * 页数
     */
    private int mPageCount;
    /**
     * 每页的Item个数
     */
    private int mItemCount;

    public CommonRefreshView(Context context) {
        this(context, null);
    }

    public CommonRefreshView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CommonRefreshView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonRefreshView);
        mRefreshEnable = ta.getBoolean(R.styleable.CommonRefreshView_crv_refreshEnable, true);
        mLoadMoreEnable = ta.getBoolean(R.styleable.CommonRefreshView_crv_loadMoreEnable, true);
        mLayoutRes = ta.getResourceId(R.styleable.CommonRefreshView_crv_layout, R.layout.view_refresh_default);
        mItemCount = ta.getInteger(R.styleable.CommonRefreshView_crv_itemCount, 10);
        ta.recycle();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(mLayoutRes, this, false);
        mContentView = view;
        addView(view);
        mSmartRefreshLayout = view.findViewById(R.id.refreshLayout);
        mSmartRefreshLayout.setOnRefreshLoadMoreListener(this);
        mEmptyLayout = view.findViewById(R.id.no_data_container);
        mLoadFailureView = view.findViewById(R.id.load_failure);
        mRecyclerView = view.findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);
        mSmartRefreshLayout.setEnableRefresh(mRefreshEnable);
        mSmartRefreshLayout.setEnableLoadMore(mLoadMoreEnable);
        View btnReload = view.findViewById(R.id.btn_reload);
        if (btnReload != null) {
            btnReload.setOnClickListener(this);
        }
    }

    @Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        refresh();
    }

    @Override
    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
        loadMore();
    }

    private final HttpCallback<HttpListData<?>> mRefreshCallback
            = new HttpCallback<HttpListData<?>>(this) {

        private int mDataCount;

        @Override
        public void onSucceed(HttpListData<?> result) {
            if (mDataHelper == null) {
                return;
            }
            if (mLoadFailureView != null && mLoadFailureView.getVisibility() == View.VISIBLE) {
                mLoadFailureView.setVisibility(View.INVISIBLE);
            }
            AppAdapter adapter;
            RecyclerView.Adapter recyclerViewAdapter = mRecyclerView.getAdapter();
            if (recyclerViewAdapter instanceof AppAdapter) {
                adapter = (AppAdapter) recyclerViewAdapter;
            } else {
                adapter = mDataHelper.getAdapter();
                if (adapter == null) {
                    return;
                }
                mRecyclerView.setAdapter(adapter);
            }
            if (result.getData() != null) {
                List<?> list = result.getData().getList();
                if (list == null) {
                    return;
                }
                mDataCount = list.size();
                if (mDataCount > 0) {
                    if (mEmptyLayout != null && mEmptyLayout.getVisibility() == View.VISIBLE) {
                        mEmptyLayout.setVisibility(View.INVISIBLE);
                    }
                    adapter.refreshData(list);
                } else {
                    adapter.clearData();
                    if (mEmptyLayout != null && mEmptyLayout.getVisibility() != View.VISIBLE) {
                        mEmptyLayout.setVisibility(View.VISIBLE);
                    }
                }
            } else {
                adapter.clearData();
                if (mEmptyLayout != null && mEmptyLayout.getVisibility() != View.VISIBLE) {
                    mEmptyLayout.setVisibility(View.VISIBLE);
                }
            }
            mDataHelper.onRefreshSuccess(adapter.getData(), adapter.getItemCount());
        }

        @Override
        public void onFail(Exception e) {
            if (mEmptyLayout != null && mEmptyLayout.getVisibility() == View.VISIBLE) {
                mEmptyLayout.setVisibility(View.INVISIBLE);
            }
            if (mLoadFailureView != null) {
                if (mLoadFailureView.getVisibility() != View.VISIBLE) {
                    if (mRecyclerView != null) {
                        RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
                        if (adapter != null && adapter.getItemCount() > 0) {
                            ToastUtils.show(R.string.load_failure);
                        } else {
                            mLoadFailureView.setVisibility(View.VISIBLE);
                        }
                    } else {
                        mLoadFailureView.setVisibility(View.VISIBLE);
                    }
                } else {
                    ToastUtils.show(R.string.load_failure);
                }
            }
            if (mDataHelper != null) {
                mDataHelper.onRefreshFailure();
            }
        }

        @Override
        public void onEnd(Call call) {
            if (mSmartRefreshLayout != null) {
                mSmartRefreshLayout.finishRefresh();
            }
        }
    };

    private final HttpCallback<HttpListData<?>> mLoadMoreCallback = new HttpCallback<HttpListData<?>>(this) {

        private int mDataCount;

        @Override
        public void onSucceed(HttpListData<?> result) {
            if (mDataHelper == null) {
                mPageCount--;
                return;
            }
            if (mLoadFailureView != null && mLoadFailureView.getVisibility() == View.VISIBLE) {
                mLoadFailureView.setVisibility(View.INVISIBLE);
            }
            if (result.getData() != null) {
                List list = result.getData().getList();
                if (list == null) {
                    mPageCount--;
                    return;
                }
                mDataCount = list.size();
                AppAdapter adapter = mDataHelper.getAdapter();
                if (mDataCount > 0) {
                    if (adapter != null) {
                        adapter.addData(list);
                    }
                } else {
                    mPageCount--;
                }
                mDataHelper.onLoadMoreSuccess(list, mDataCount);
            } else {
                mPageCount--;
            }
        }

        @Override
        public void onFail(Exception e) {
            mPageCount--;
            if (mDataHelper != null) {
                mDataHelper.onLoadMoreFailure();
            }
        }

        @Override
        public void onEnd(Call call) {
            if (mSmartRefreshLayout != null) {
                if (mDataCount < mItemCount) {
                    mSmartRefreshLayout.finishLoadMore();
                    mSmartRefreshLayout.setNoMoreData(true);
                } else {
                    mSmartRefreshLayout.finishLoadMore();
                }
            }
        }
    };

    public <T> void setDataHelper(DataHelper<T> dataHelper) {
        mDataHelper = dataHelper;
    }

    public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
        mRecyclerView.setLayoutManager(layoutManager);
    }

    public void setItemDecoration(RecyclerView.ItemDecoration itemDecoration) {
        mRecyclerView.addItemDecoration(itemDecoration);
    }


    public void showLoading() {
        mPageCount = 1;
        if (mSmartRefreshLayout != null) {
            mSmartRefreshLayout.autoRefreshAnimationOnly();
        }
        if (mEmptyLayout != null && mEmptyLayout.getVisibility() == VISIBLE) {
            mEmptyLayout.setVisibility(INVISIBLE);
        }
        if (mLoadFailureView != null && mLoadFailureView.getVisibility() == VISIBLE) {
            mLoadFailureView.setVisibility(INVISIBLE);
        }
    }

    public void showEmpty() {
        if (mEmptyLayout != null && mEmptyLayout.getVisibility() != VISIBLE) {
            mEmptyLayout.setVisibility(VISIBLE);
        }
    }

    public void hideEmpty() {
        if (mEmptyLayout != null && mEmptyLayout.getVisibility() == VISIBLE) {
            mEmptyLayout.setVisibility(INVISIBLE);
        }
    }

    public void hideLoadFailure() {
        if (mLoadFailureView != null && mLoadFailureView.getVisibility() == VISIBLE) {
            mLoadFailureView.setVisibility(INVISIBLE);
        }
    }


    public void initData() {
        refresh();
    }

    public void refresh() {
        if (mDataHelper != null) {
            mPageCount = 1;
            mDataHelper.loadData(mPageCount, mRefreshCallback);
        }
    }

    public void loadMore() {
        if (mDataHelper != null) {
            mPageCount++;
            mDataHelper.loadData(mPageCount, mLoadMoreCallback);
        }
    }

    public int getPageCount() {
        return mPageCount;
    }

    public void setPageCount(int pageCount) {
        mPageCount = pageCount;
    }


    public int getItemCount() {
        return mItemCount;
    }

    public void setItemCount(int itemCount) {
        mItemCount = itemCount;
    }

    public void setRefreshEnable(boolean enable) {
        if (mSmartRefreshLayout != null) {
            mSmartRefreshLayout.setEnableRefresh(enable);
        }
    }

    public void setLoadMoreEnable(boolean enable) {
        if (mSmartRefreshLayout != null) {
            mSmartRefreshLayout.setEnableLoadMore(enable);
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_reload) {
            refresh();
        }
    }

    public interface DataHelper<T> {

        AppAdapter<T> getAdapter();

        void loadData(int p, HttpCallback<HttpListData<T>> callback);

        /**
         * 下拉刷新成功
         *
         * @param list      Adapter的全部数据的List
         * @param listCount Adapter的全部数据的个数
         */
        void onRefreshSuccess(List<T> list, int listCount);

        /**
         * 下拉刷新失败
         */
        void onRefreshFailure();

        /**
         * 上拉加载成功
         *
         * @param loadItemList  本次加载到的数据
         * @param loadItemCount 加载到的数据个数
         */
        void onLoadMoreSuccess(List<T> loadItemList, int loadItemCount);

        /**
         * 加载失败
         */
        void onLoadMoreFailure();
    }

    @Override
    public void onSucceed(Object result) {

    }

    @Override
    public void onFail(Exception e) {

    }

    /**
     * 空数据的布局
     */
    public void setEmptyLayoutId(int noDataLayoutId) {
        if (mEmptyLayout != null) {
            mEmptyLayout.removeAllViews();
            View v = LayoutInflater.from(mContext).inflate(noDataLayoutId, mEmptyLayout, false);
            LayoutParams params = (LayoutParams) v.getLayoutParams();
            params.gravity = Gravity.CENTER;
            v.setLayoutParams(params);
            mEmptyLayout.addView(v);
        }
    }

    public View getContentView() {
        return mContentView;
    }

    public WrapRecyclerView getRecyclerView() {
        return mRecyclerView;
    }

    public void setRecyclerViewAdapter(AppAdapter adapter) {
        if (mRecyclerView != null) {
            mRecyclerView.setAdapter(adapter);
        }
    }

}
